package planit.model;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Observable;
import java.io.Serializable;
import planit.util.ExtendedDate;


public class Schedule extends Observable implements Serializable{
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	public enum ChangeType {
		EVENT,
		PERSON,
		GROUP,
		EVENTTYPE,
		CHECKOUT
	}

	private Map<Integer, Event> events 			= new HashMap<Integer, Event>();
	private Map<Integer, Group> groups 			= new HashMap<Integer, Group>();
	private Map<Integer, Person> persons 		= new HashMap<Integer, Person> ();
	private Map<Integer, EventType> eventTypes 	= new HashMap<Integer, EventType>(); 
	
	public void addEvent(Event e){
		setChanged();
		events.put(e.getId(), e);
		notifyObservers(ChangeType.EVENT);
	}
	
	public void removeEvent(Event e){
		setChanged();
		events.remove(e.getId());
		notifyObservers(ChangeType.EVENT);
	}

	public void addGroup(Group g){
		setChanged();
		groups.put(g.getId(), g);
		notifyObservers(ChangeType.GROUP);
	}
	
	public void updateAfterCheckout() {
		setChanged();
		notifyObservers(ChangeType.CHECKOUT);
	}
	
	public void removeGroup(Group g){
		//deprecated?? Doesn't work like intended anymore.
		//if(getSelectedGroup() > 1)
		if(g.getId() != 0)
		groups.remove(g.getId());
		//handling if id is 0?
		setChanged();
		notifyObservers(ChangeType.GROUP);
	}
	
	public void addPerson(Person person){
		setChanged();
		persons.put(person.getId(), person);
		notifyObservers(ChangeType.PERSON);
	}

	public void removePerson(Person person){
		setChanged();
		persons.remove(person.getId());
		notifyObservers(ChangeType.PERSON);
	}
	
	public void addEventType(EventType eventType){
		setChanged();
		eventTypes.put(eventType.getId(),eventType);
		notifyObservers(ChangeType.EVENTTYPE);
	}

	public void removeEventType(EventType eventType){
		setChanged();
		eventTypes.remove(eventType.getId());
		notifyObservers(ChangeType.EVENTTYPE);
	}
	
	public Collection<Event> getEvents() {
		return events.values();
	}

	public ArrayList<Event> getEvents(Date startTime, Date endTime) {
		ArrayList<Event> returnValue = new ArrayList<Event>();
		
		for(Event e : events.values()){
			if (e.getStartTime().compareTo(startTime) > 0 && e.getStartTime().compareTo(endTime) < 0 ||
					ExtendedDate.dateWithAddedMinutes(e.getStartTime(), e.getDuration()).compareTo(startTime) > 0 
					&& ExtendedDate.dateWithAddedDays(e.getStartTime(), e.getDuration()).compareTo(endTime) < 0){
				returnValue.add(e);
			}
		}	
		return returnValue;
	}
	
	public Collection<EventType> getEventTypes(){
		return eventTypes.values();
	}
	
	public ArrayList<Group> getGroupsForPerson(Person p) {
		ArrayList<Group> returnValue = new ArrayList<Group>();
		for(Group g : groups.values()){
			if (g.getPersons().contains(p)){
				returnValue.add(g);
			}
		}
		return returnValue;
	}
	
	public Collection<Group> getGroups(){
		return groups.values();
	}
	
	public Collection<Person> getPersons(){
		return persons.values();
	}
	
	public ArrayList<Person> getAllPersons(){
		ArrayList<Person> pers = new ArrayList<Person>();
		pers.addAll(persons.values());
		return pers;
	}
	
	public Group getGroup(int id) {
		return groups.get(id);
	}
	
	public Event getEvent(int id) {
		return events.get(id);
	}
	
	public Person getPerson(int id) {
		return persons.get(id);
	}
	
	public EventType getEventType(int id) {
		return eventTypes.get(id);
	}

}
